#!/usr/bin/python
# -*- coding: UTF-8 -*-

import rospy
from std_srvs.srv import (
    Trigger, TriggerRequest, TriggerResponse
)
from cln_msgs.msg import (
    HardwareCtrl,CleanDeviceType,HardwareStateType
)
from v3_msgs.msg import (
    VersionInfo, Version
)
from v3_msgs.srv import (
    OTAManager,OTAManagerRequest,OTAManagerResponse
)

class OTA_Parser:
    def __init__(self):
        pass

    def InitParser(self, node_name):
        self.__restart_peripherals_ctrl_pub = rospy.Publisher("/restart_peripherals_ctrl", HardwareCtrl, queue_size=1)
        self.__ipc_reboot_client = rospy.ServiceProxy('/ipc_reboot', Trigger)
        self.__ota_manager_client = rospy.ServiceProxy('/ota_upgrade_server', OTAManager)
        self.__ota_upgrade_state = VersionInfo()
        rospy.Subscriber("/ota_upgrade_state", VersionInfo, self.UpgradeStateCallback)

    def ResDataInit(self):
        '''
            初始化返回数据
        '''
        return {
            "code": 0,
            "msg": "success",
        }

    def ResDataError(self, msg = "failed"):
        '''
            返回异常数据
        '''
        return {
            "code": -1,
            "msg": msg,
        }
    
    def UpgradeStateCallback(self, msg):
        '''升级状态回调函数'''
        self.__ota_upgrade_state = msg
    
    def RobotReboot(self, data):
        '''工控机重启'''
        ret_dat = self.ResDataInit()
        try:
            if "outage_reboot" in data and data["outage_reboot"] == 1:
                # outage_reboot 1 整机断电重启
                device_msg = CleanDeviceType()
                device_msg.value = 210
                state_msg = HardwareStateType()
                state_msg.state = state_msg.REBOOT
                hardware_ctrl_msg = HardwareCtrl()
                hardware_ctrl_msg.device_id.append(device_msg)
                hardware_ctrl_msg.state.append(state_msg)
                self.__restart_peripherals_ctrl_pub.publish(hardware_ctrl_msg)
            else:
                self.__ipc_reboot_client.call(TriggerRequest())  #工控机重启
        except Exception as error:
            ret_dat = self.ResDataError("[RobotReboot] error: {}".format(error)) 
        finally:
            return ret_dat

    def OTAManagerServer(self, option):
        '''
            升级服务
        '''
        ret_dat = dict()
        client_data = OTAManagerRequest()
        try:
            client_data.option = option
            resp = self.__ota_manager_client(client_data)
            if not resp.response.success:
                raise Exception(resp.response.message) 
            ret_dat["cloudplatform_token"] = resp.cloudplatform_token
            ret_dat["robot_sn"] = resp.robot_sn
            ret_dat["robot_type"] = resp.robot_type
            ret_dat["robot_type_sw"] = resp.robot_type_sw
            ret_dat["step"] = resp.version_info.curr_step
            ret_dat["step_list"] = resp.version_info.step_list
            ret_dat["upgrade_progress"] = resp.version_info.upgrade_progress
            ret_dat["error_code"] = resp.response.error_code.error_code
            ret_dat["error_message"] = resp.response.error_code.error_msg
            if option == OTAManagerRequest.CHECK_UPDATE:
                ret_dat["version"] = resp.version_info.major_version.latest_version
            else:
                ret_dat["version"] = resp.version_info.major_version.local_version
            ret_dat["up_to_date"] = resp.version_info.major_version.up_to_date
            if resp.version_info.update_log:
                ret_dat["update_log"] = resp.version_info.update_log[0]      #先返回首个数据
            else:
                ret_dat["update_log"] = ""
            ret_dat["sw"] = {
                "version" : resp.version_info.software_version.local_version,
                "latest_version" : resp.version_info.software_version.latest_version,
                "download_progress" : resp.version_info.software_version.download_progress,
                "up_to_date" : resp.version_info.software_version.up_to_date
            }
            ret_dat["app"] = {
                "version" : resp.version_info.app_version.local_version,
                "latest_version" : resp.version_info.app_version.latest_version,
                "download_progress" : resp.version_info.app_version.download_progress,
                "up_to_date" : resp.version_info.app_version.up_to_date
            }
            ret_dat["hw"] = {
                "version" : resp.version_info.hardware_version.local_version,
                "latest_version" : resp.version_info.hardware_version.latest_version,
                "download_progress" : resp.version_info.hardware_version.download_progress,
                "up_to_date" : resp.version_info.hardware_version.up_to_date
            }
        except Exception as error:
            rospy.logerr("[OTAManagerServer] error: {}".format(error))  
        finally:
            return ret_dat
        
    def GetVersionInfo(self):
        '''获取版本更新内容 旧接口兼容'''
        ret_dat = self.ResDataInit()
        try:
            resp = self.OTAManagerServer(OTAManagerRequest.LOCAL_VERSION)
            if not resp:
                raise Exception("get response data error.")
            version_data = {
                "type": resp["robot_type"],
                "sn": resp["robot_sn"],
                "versionNow": resp["sw"]["version"],
                "versionNew": "",
                "versionSize": str(0.0),
                "uploadLog": resp["update_log"],
                "versionNow_Hardware": resp["hw"]["version"],
                "versionNew_Hardware": "",
                "updateLog_Hardware": "",
                "token": resp["cloudplatform_token"],
                "type_sw": resp["robot_type_sw"],            #配置类型 新增字段
                "version": resp["version"],                  #大版本 新增字段
            }
            ret_dat.update(version_data)
        except Exception as error:
            ret_dat = self.ResDataError("[GetVersionInfo] error: {}".format(error))  
        finally:
            return ret_dat

    def GetVersionInfoV3(self):
        '''获取版本更新内容 新接口，后续统一对外使用'''
        ret_dat = self.ResDataInit()
        try:
            resp = self.OTAManagerServer(OTAManagerRequest.LOCAL_VERSION)
            if not resp:
                raise Exception("get response data error.")
            ret_dat["data"] = resp
        except Exception as error:
            ret_dat = self.ResDataError("[GetVersionInfo] error: {}".format(error))  
        finally:
            return ret_dat
        
    def CheckVersionUpdate(self):
        ret_dat = self.ResDataInit()
        try:
            resp = self.OTAManagerServer(OTAManagerRequest.CHECK_UPDATE)
            if not resp:
                raise Exception("get response data error.")
            ret_dat["data"] = resp
        except Exception as error:
            ret_dat = self.ResDataError("[CheckVersionUpdate] error: {}".format(error))  
        finally:
            return ret_dat  

    def StartUpdating(self, data):
        ret_dat = self.ResDataInit()
        try:
            if not data : 
                raise Exception("Request data error!")
            if not "option" in data:
                raise Exception("option is empty!")
            option = data["option"]
            req_option = OTAManagerRequest.UPDATE_STATE
            if option == 1:
                req_option = OTAManagerRequest.START_UPDATE
            resp = self.OTAManagerServer(req_option)
            if not resp:
                raise Exception("get response data error.")
            ret_dat["data"] = resp
        except Exception as error:
            ret_dat = self.ResDataError("[CheckVersionUpdate] error: {}".format(error))  
        finally:
            return ret_dat                
    
  



